package foundation.SurModel;

import java.util.List;

import Jama.Matrix;

public class GaussianSM {

	// 单例
	private static GaussianSM gaussSM = null;

	// 训练数据集中输入部分，每一元素是double型染色体编码并已将没有使用的处理器置为0
	Matrix X = null;
	// 训练数据集中的输出部，每一元素是对应X中元素编码的响应时间
	Matrix Y = null;
	// 22个seta参数
	double[] seta = { 0.22166831292161238, 5.388442833775635E-4, 3.227302613318422E-5, 2.7512026384236733E-12,
			7.64469964431475E-5, 2.7339483565144425E-4, 0.0013584596033846615, 3.253393422970333E-5,
			0.012599773774036049, 1.2871357063418828E-7, 1.2747032354496595E-11, 0.006479781046818112,
			0.04099090169357382, 4.2674231590651973E-11, 0.02121522353972778, 1.962159075823359E-6,
			1.0315078652740483E-13, 1.5843448012818696E-11, 1.39103532030636E-7, 5.41887504323966E-7,
			0.07707216528572566, 3.9784629490310824E-14 };

	// 22个P参数
	double[] p = { 1.569852327179218, 1.4248840806196221, 1.2175844778990037, 1.864659855530153, 1.1658250675498778,
			1.1456612298409072, 1.1948684163304863, 1.4050669856981437, 1.49576536924544, 1.9858792209345588,
			1.5339047214130672, 1.821272716033029, 1.7245496928743884, 1.0963223158499082, 1.200581238725017,
			1.6236935041424088, 1.2406888963912965, 1.8311502145589336, 1.1118877751794265, 1.4511980749173468,
			1.4937450989120307, 1.160179318823952 };

	// 输入X的协方差矩阵
	Matrix covMat = null;
	// 均值
	double meanVal = 0d;
	// 方差
	double variVal = 0d;

	public static GaussianSM getInstance() {// 获取实例的唯一入口
		if (gaussSM == null) {
			gaussSM = new GaussianSM();
		}
		return gaussSM;
	}

	private GaussianSM() {// 注意构造函数是私有的
		// 训练数据集，目前是样本集的200个记录
		Matrix[] data = InOut.load("!!SMDFGA", 0, 200,"");
		X = data[0];
		Y = data[1];

		// 计算样本X的协方差
		covMat = Predictor.getCovMat(X, seta, p);
		// 计算均值
		meanVal = Predictor.getMeanVal(covMat, Y);
		// 计算方差
		variVal = Predictor.getVariVal(covMat, meanVal, Y);
	}

	/**
	 * 获取染色体的预审值
	 * 
	 * @param codes:染色体的字符串编码（各元素是浮点型数）
	 * @return：预审的适应度值
	 */
	public float prescreen(List<StringBuffer> codes) {
		float preFitVal = -1f;
		int size = codes.size();
		double[] dblCodes = new double[size];
		// 将字符编码转化为浮点编码，这后面要考虑重构
		dblCodes = InOut.toDlbCodes(codes);

		InOut.postDblCodePros(dblCodes);// 把未用的处理器速度置为0
		// preVals[0]放的预测值，preVals[1]放的是对应的方差
		double[] preVals = Predictor.predict(X, dblCodes, Y, covMat, p, seta, meanVal, variVal);
		preFitVal = (float) (preVals[0]);
		// preFitVal=(float)(preVals[0]-2*preVals[1]);
		return preFitVal;
	}

}
